let myfn = {}
import LoginModule from '@/common/js/login.js'
import UploadModule from '@/common/js/upload.js'
import upgradeModule from '@/common/js/appUpgrade.js'
import secureModule from '@/common/js/secure.js'
import tokenModule from '@/common/js/token.js'

myfn.wgs84ToGcj02 = (lng, lat) => {
  const A = 6378245.0
  const EE = 0.006693421622965943

  const isOutOfChina = (lng, lat) => {
    return lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271
  }

  const transformLat = (x, y) => {
    let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x))
    ret += ((20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0) / 3.0
    ret += ((20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin((y / 3.0) * Math.PI)) * 2.0) / 3.0
    ret += ((160.0 * Math.sin((y / 12.0) * Math.PI) + 320 * Math.sin((y * Math.PI) / 30.0)) * 2.0) / 3.0
    return ret
  }

  const transformLng = (x, y) => {
    let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x))
    ret += ((20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0) / 3.0
    ret += ((20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin((x / 3.0) * Math.PI)) * 2.0) / 3.0
    ret += ((150.0 * Math.sin((x / 12.0) * Math.PI) + 300.0 * Math.sin((x / 30.0) * Math.PI)) * 2.0) / 3.0
    return ret
  }

  if (isOutOfChina(lng, lat)) {
    return { lng, lat }
  }

  let dLat = transformLat(lng - 105.0, lat - 35.0)
  let dLng = transformLng(lng - 105.0, lat - 35.0)
  const radLat = (lat / 180.0) * Math.PI
  let magic = Math.sin(radLat)
  magic = 1 - EE * magic * magic
  const sqrtMagic = Math.sqrt(magic)

  dLat = (dLat * 180.0) / (((A * (1 - EE)) / (magic * sqrtMagic)) * Math.PI)
  dLng = (dLng * 180.0) / ((A / sqrtMagic) * Math.cos(radLat) * Math.PI)

  return {
    lng: lng + dLng,
    lat: lat + dLat
  }
}

myfn.getLocation = (options = {}) => {
  return new Promise((resolve, reject) => {
    console.log('获取定位==>')

    const platform = uni.getSystemInfoSync().platform
    const isIOS = platform === 'ios'

    const locationConfig = {
      type: isIOS ? 'gcj02' : 'gcj02',
      geocode: true
    }
    vk.showLoading('获取定位中...')
    console.log('locationConfig==> ', locationConfig)
    uni.getLocation({
      ...locationConfig,
      success: function (res) {
        console.log('允许定位==>', res)
        resolve(res)

        let positioning, currentLatLng

        if (isIOS) {
          const gcj02 = vk.myfn.wgs84ToGcj02(res.longitude, res.latitude)
          console.log('gcj02==>', gcj02)

          positioning = {
            lat: res.latitude,
            lng: res.longitude,
            address: res.address.poiName
          }
          currentLatLng = { lat: res.latitude, lng: res.longitude }
        } else {
          positioning = {
            lat: res.latitude,
            lng: res.longitude,
            address: res.address.poiName
          }
          currentLatLng = { lat: res.latitude, lng: res.longitude }
        }

        vk.setVuex('$user.positioning', positioning)
        vk.setVuex('$app.currentLatitudeAndLongitude', currentLatLng)
        vk.setVuex('$app.checkLocationPermission.isOpen', true)

        vk.setVuex('$app.homePageUpdate', Math.random())
      },
      fail: function (err) {
        reject(err)
        console.log('不允许定位==>', err)

        vk.setVuex('$app.checkLocationPermission.isOpen', false)
        vk.setVuex('$user.positioning', { lat: '', lng: '', address: '' })
        vk.setVuex('$app.homePageUpdate', Math.random())
      },
      complete: function () {
        vk.hideLoading()
      }
    })
  })
}

myfn.httpBuildQuery = (data, numericPrefix = '', argSeparator = '&') => {
  const params = []

  function encode(value, key = '') {
    if (typeof value === 'object' && value !== null && !(value instanceof Date)) {
      const isArray = Array.isArray(value)

      for (const prop in value) {
        if (value.hasOwnProperty(prop)) {
          let newKey

          if (key === '') {
            newKey = isArray ? `${numericPrefix}${prop}` : prop
          } else {
            newKey = `${key}[${prop}]`
          }

          encode(value[prop], newKey)
        }
      }
    } else {
      let val
      if (value === null || value === undefined) {
        val = ''
      } else if (typeof value === 'boolean') {
        val = value ? '1' : '0'
      } else {
        val = String(value)
      }

      params.push(`${encodeURIComponent(key)}=${encodeURIComponent(val)}`)
    }
  }

  encode(data)
  return params.join(argSeparator)
}

myfn.openLocationSettings = () => {
  const systemInfo = uni.getSystemInfoSync()

  if (systemInfo.platform === 'android') {
    try {
      const Intent = plus.android.importClass('android.content.Intent')
      const Settings = plus.android.importClass('android.provider.Settings')
      const main = plus.android.runtimeMainActivity()

      const intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
      main.startActivity(intent)
    } catch (e) {
      console.error('Android跳转定位设置失败:', e)
      try {
        const Intent = plus.android.importClass('android.content.Intent')
        const Settings = plus.android.importClass('android.provider.Settings')
        const Uri = plus.android.importClass('android.net.Uri')
        const main = plus.android.runtimeMainActivity()

        const intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
        const uri = Uri.parse('package:' + main.getPackageName())
        intent.setData(uri)
        main.startActivity(intent)
      } catch (err) {
        console.error('Android跳转应用设置失败:', err)
        uni.showToast({
          title: '请手动前往设置开启定位权限',
          icon: 'none'
        })
      }
    }
  } else if (systemInfo.platform === 'ios') {
    try {
      plus.runtime.openURL('app-settings:')
    } catch (e) {
      console.error('iOS跳转设置失败:', e)
      uni.showToast({
        title: '请手动前往设置开启定位权限',
        icon: 'none'
      })
    }
  }

  uni.showToast({
    title: '当前环境不支持跳转设置',
    icon: 'none'
  })
}

myfn.checkLocationPermission = () => {
  const systemInfo = uni.getSystemInfoSync()

  if (systemInfo.platform === 'android') {
    try {
      const main = plus.android.runtimeMainActivity()
      const Context = plus.android.importClass('android.content.Context')
      const LocationManager = plus.android.importClass('android.location.LocationManager')
      const PackageManager = plus.android.importClass('android.content.pm.PackageManager')

      const permission = 'android.permission.ACCESS_FINE_LOCATION'
      const hasPermission = main.checkSelfPermission(permission) === PackageManager.PERMISSION_GRANTED

      if (!hasPermission) {
        return false
      }

      const locationManager = main.getSystemService(Context.LOCATION_SERVICE)
      const isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
      const isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)

      return isGpsEnabled || isNetworkEnabled
    } catch (e) {
      console.error('Android定位权限检测失败:', e)

      return false
    }
  } else if (systemInfo.platform === 'ios') {
    try {
      const CLLocationManager = plus.ios.importClass('CLLocationManager')
      const authorizationStatus = CLLocationManager.authorizationStatus()

      const isAuthorized = authorizationStatus === 3 || authorizationStatus === 4

      if (!isAuthorized) {
        return false
      }

      const locationServicesEnabled = CLLocationManager.locationServicesEnabled()

      return locationServicesEnabled
    } catch (e) {
      console.error('iOS定位权限检测失败:', e)
      return false
    }
  }

  return true
}

myfn.refreshToken = () => {
  if (!vk.checkToken()) {
    return
  }
  const keyName = 'pub-vk.userCenter.loginByToken'
  let time = vk.getStorageSync(keyName) || 0
  const { todayStart, todayEnd } = vk.pubfn.getCommonTime()
  if (time >= todayStart && time <= todayEnd) {
    console.log('今日执行过loginByToken')
    return
  }
  api
    .refreshToken({
      refreshToken: vk.getStorageSync('refresh_token')
    })
    .then(res => {
      console.log('刷新token成功:', res)
      vk.setStorageSync('uni_id_token', res.data.token)
      vk.setStorageSync('uni_id_token_expired', res.data.expire_time)
      vk.setStorageSync(keyName, todayEnd)
    })
}

myfn.secure = () => secureModule.secure()

myfn.checkWechatInstalled = () => {
  try {
    return plus.runtime.isApplicationExist({
      pname: 'com.tencent.mm',
      action: 'weixin://'
    })
  } catch (e) {
    console.error('检查微信安装状态失败:', e)
    return false
  }

  return false
}

myfn.vibrate = () => {
  const platform = uni.getSystemInfoSync().platform
  if (platform === 'ios') {
    const UIImpactFeedbackGenerator = plus.ios.importClass('UIImpactFeedbackGenerator')
    const impact = new UIImpactFeedbackGenerator()
    impact.prepare()
    impact.init(1)
    impact.impactOccurred()
  } else if (platform === 'android') {
    uni.vibrateShort()
  }
}

myfn.upgrade = () => upgradeModule.upgrade()

myfn.navigateBackRefresh = () => {
  vk.navigateBack()
}

myfn.checkNotificationStatus = () => {
  return new Promise(resolve => {
    const systemInfo = uni.getSystemInfoSync()

    if (systemInfo.platform === 'android') {
      try {
        const main = plus.android.runtimeMainActivity()
        const NotificationManagerCompat = plus.android.importClass('androidx.core.app.NotificationManagerCompat')
        const enabled = NotificationManagerCompat.from(main).areNotificationsEnabled()
        resolve({
          enabled,
          platform: 'android'
        })
      } catch (e) {
        console.error('Android通知权限检测失败:', e)
        resolve({
          enabled: false,
          platform: 'android',
          error: e
        })
      }
    } else if (systemInfo.platform === 'ios') {
      try {
        const UNUserNotificationCenter = plus.ios.importClass('UNUserNotificationCenter')
        const center = UNUserNotificationCenter.currentNotificationCenter()

        center.getNotificationSettingsWithCompletionHandler(settings => {
          const enabled = settings.authorizationStatus === 2
          resolve({
            enabled,
            platform: 'ios',
            authorizationStatus: settings.authorizationStatus
          })
        })
      } catch (e) {
        console.error('iOS通知权限检测失败:', e)
        resolve({
          enabled: false,
          platform: 'ios',
          error: e
        })
      }
    }

    resolve({
      enabled: true,
      platform: 'other'
    })
  })
}

myfn.isIOS = () => {
  return uni.getSystemInfoSync().platform === 'ios'

  return false
}

myfn.reloadPage = () => {
  const pages = getCurrentPages()
  const cur = pages[pages.length - 1]
  const route = cur.route
  const options = cur.options || {}
  const query = Object.keys(options)
    .map(k => `${k}=${encodeURIComponent(options[k])}`)
    .join('&')

  uni.reLaunch({
    url: `/${route}${query ? '?' + query : ''}`
  })
}

myfn.isLogin = () => {
  const userInfo = vk.getVuex('$user.userInfo')
  if (Object.keys(userInfo).length > 0) return true
  vk.myfn.login()
  return false
}

myfn.formatDateTime = timestamp => {
  const date = new Date(Number(timestamp) * 1000)

  const year = date.getFullYear()
  const month = String(date.getMonth() + 1).padStart(2, '0')
  const day = String(date.getDate()).padStart(2, '0')
  const hours = String(date.getHours()).padStart(2, '0')
  const minutes = String(date.getMinutes()).padStart(2, '0')
  const seconds = String(date.getSeconds()).padStart(2, '0')

  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}

myfn.shareWithSystem = () => {
  uni.shareWithSystem({
    type: 'text',
    summary: '欢迎入驻「钓点达人 App」',
    href: 'https://www.diaodiandaren.com/api/page/download?server=true',
    success() {},
    fail() {}
  })

  vk.alert('当前环境不支持系统分享功能')
}

myfn.logout = () => {
  return new Promise(resolve => {
    uni.clearStorageSync()
    vk.setVuex('$user.userInfo', {})
    vk.setVuex('$user.token', '')
    vk.reLaunch('/pages/index/index')
    resolve()
  })
}

myfn.login = () => LoginModule.login()

myfn.wxLogin = () => LoginModule.wxLogin()

myfn.appleLogin = () => LoginModule.appleLogin()

myfn.handleImageUrl = url => {
  if (!url) return ''
  if (url.startsWith('http://') || url.startsWith('https://')) {
    return url
  }
  return `${vk.vuex.get('$app.initData.site.cdnUrl') || vk.getConfig().imageUrl}${url.startsWith('/') ? '' : '/'}${url}`
}

myfn.validatePhone = phone => {
  const reg = /^1[3-9]\d{9}$/
  return reg.test(phone)
}

myfn.previewImage = (options = {}) => {
  return new Promise((resolve, reject) => {
    const { urls = [], current = 0 } = options

    const imageUrls = urls.map(url => myfn.handleImageUrl(url))

    let currentImg = current
    if (typeof current === 'string') {
      currentImg = myfn.handleImageUrl(current)
    }

    uni.previewImage({
      urls: imageUrls,
      current: currentImg,
      success: res => {
        resolve(res)
      },
      fail: err => {
        console.error('预览图片失败:', err)
        reject(err)
      }
    })
  })
}

myfn.formatTime = date => {
  const formatter = new Date(date.replace(/-/g, '/'))

  const now = new Date()
  const diff = Math.abs(now - formatter) / 1000
  const intervals = {
    年: 31536000,
    个月: 2592000,
    天: 86400,
    小时: 3600,
    分钟: 60,
    秒: 1
  }
  for (let unit in intervals) {
    const value = Math.floor(diff / intervals[unit])
    if (value > 0) {
      return value === 1 ? `1 ${unit}前` : `${value} ${unit}前`
    }
  }
  return '刚刚'
}

myfn.objToString = obj => {
  let str = '?'
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      str += `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}&`
    }
  }
  return str.slice(0, -1)
}

myfn.openMap = (latitude, longitude, name, scale) => {
  uni.openLocation({
    latitude,
    longitude,
    name,
    scale
  })
}

myfn.copyToClipboard = text => {
  return new Promise((resolve, reject) => {
    uni.setClipboardData({
      data: text,
      success: () => {
        uni.showToast({
          title: '复制成功',
          icon: 'success'
        })
        resolve()
      },
      fail: reject
    })
  })
}

myfn.chooseLocation = () => {
  return new Promise((resolve, reject) => {
    uni.chooseLocation({
      success: res => {
        const location = {
          name: res.name,
          address: res.address,
          latitude: res.latitude,
          longitude: res.longitude
        }
        resolve(location)
      },
      fail: err => {
        if (err.errMsg.includes('cancel')) {
          uni.showToast({
            title: '已取消选择',
            icon: 'none'
          })
        } else {
          uni.showToast({
            title: '选择位置失败',
            icon: 'none'
          })
        }
        reject(err)
      }
    })
  })
}

myfn.getTimeAgo = timestamp => {
  const now = Date.now()
  const time = new Date(timestamp).getTime()
  const diff = now - time

  const minute = 60 * 1000
  const hour = 60 * minute
  const day = 24 * hour
  const month = 30 * day
  const year = 365 * day

  if (diff < minute) {
    return '刚刚'
  } else if (diff < hour) {
    return Math.floor(diff / minute) + '分钟前'
  } else if (diff < day) {
    return Math.floor(diff / hour) + '小时前'
  } else if (diff < month) {
    return Math.floor(diff / day) + '天前'
  } else if (diff < year) {
    return Math.floor(diff / month) + '个月前'
  } else {
    return Math.floor(diff / year) + '年前'
  }
}

export default myfn
